package gops

import (
	"sync"
)

// [T any] 表示该函数是一个泛型函数，具有一个类型参数 T，其中 any 是对 interface{} 的别名，表示 T 可以是任何类型
// GoroutineConcurrentCollect 并发执行任务并收集结果（线程安全）
// 参数说明：
//
//	n: 并发任务数量
//	taskFunc: 任务处理函数（接收任务序号，返回结果和错误）
func GoroutineConcurrentCollect[T any](n int, taskFunc func(int) (T, error)) ([]T, []error) {
	var (
		results = make([]T, 0, n)
		errors  = make([]error, 0, n)
		wg      sync.WaitGroup
		resCh   = make(chan T, n)
		errCh   = make(chan error, n)
	)

	// 启动并发任务
	wg.Add(n)
	for i := 0; i < n; i++ {
		go func(taskID int) {
			defer wg.Done()
			res, err := taskFunc(taskID)
			if err != nil {
				errCh <- err
			} else {
				resCh <- res
			}
		}(i)
	}

	// 等待所有任务完成
	wg.Wait()
	close(resCh)
	close(errCh)

	// 收集结果
	for res := range resCh {
		results = append(results, res)
	}
	for err := range errCh {
		errors = append(errors, err)
	}

	return results, errors
}

//// 定义独立的任务处理函数
//func squareTask(taskID int) (int, error) {
//	if taskID%7 == 0 {
//		return 0, fmt.Errorf("invalid task %d", taskID)
//	}
//	return taskID * taskID, nil
//}
//
//func main() {
//	// 调用并发收集函数，传入独立任务函数
//	squares, errs := GoroutineConcurrentCollect(10, squareTask)
//
//	fmt.Println("Results:", squares) // [1 4 9 16 25 36 64 81]
//	fmt.Println("Errors:", errs)     // [invalid task 0, invalid task 7]
//}
